package com.baikeyang.app.controller;

import com.baikeyang.common.constant.CommonConstants;
import com.baikeyang.common.model.SystemLog;
import com.baikeyang.common.util.StringUtils;
import com.baikeyang.common.util.shiro.SecurityUtil;
import com.baikeyang.service.logs.ISystemLogService;
import com.baikeyang.service.user.IUserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;

/**
 * 用户登录/登出控制器
 * Created by lenovo on 2018/7/12.
 */
@RestController(value = "loginController")
@RequestMapping(value = "/")
public class LoginController {

    private static final Logger log = LogManager.getLogger(LoginController.class);

    @Autowired
    private IUserService userService;

    @Autowired
    private ISystemLogService systemLogService;


    /**
     * @title toLogin
     * @description 跳转至登录页面
     * @return ModelAndView
     */
    @RequestMapping(value = "login")
    public ModelAndView login(){
        return new ModelAndView("login");
    }

    @RequestMapping(value = "hash_login")
    public ModelAndView hashLogin() {
        return new ModelAndView("");
    }

    /**
     * @title login
     * @description 用户登录
     * @param username 登录账号
     * @param password 登录密码
     * @return ModelAndView
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ModelAndView login(HttpServletRequest request,
                              HttpServletResponse response,
                              @RequestParam("username") String username,
                              @RequestParam("password") String password) {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        String emsg = "";
        try {
            subject.login(token);

            String strMethodName = "login";
            String strClassName = this.getClass().getName();
            StringBuffer bfParams = new StringBuffer();

            Enumeration<String> paraNames = null;
            paraNames = request.getParameterNames();
            String key;
            String value;
            while (paraNames.hasMoreElements()) {
                key = paraNames.nextElement();
                value = request.getParameter(key);
                bfParams.append(key).append("=").append(value).append("&");
            }
            if (StringUtils.isBlank(bfParams)) {
                bfParams.append(request.getQueryString());
            }

            String strMessage = String
                    .format("[类名]:%s,[方法]:%s,[参数]:%s", strClassName, strMethodName, bfParams.toString());
            log.info(strMessage);

            SystemLog sysLog = new SystemLog();
            sysLog.setLoginName(username);
            sysLog.setRoleName(StringUtils.isNotEmpty(username)?username:"admin");
            sysLog.setOptContent(strMessage);
            sysLog.setCreateTime(new Date());
            if (request != null) {
                //sysLog.setClientIp(request.getRemoteAddr());
                sysLog.setClientIp(getNetIP(request));
            }
            log.info(sysLog.toString());
            systemLogService.save(sysLog);

            return new ModelAndView("redirect:" + "/admin");
        } catch (UnknownAccountException unknownAccountException) {
            log.error("登录失败:账号不正确", unknownAccountException);
            emsg = "登录失败:账号不正确";
            return new ModelAndView("/login").addObject("msg", emsg);
        } catch (IncorrectCredentialsException incorrectCredentialsException) {
            incorrectCredentialsException.printStackTrace();
            log.error("登录失败:密码错误", incorrectCredentialsException);
            emsg = "登录失败:密码错误";
            return new ModelAndView("/login").addObject("msg", emsg);
        }  catch (ExcessiveAttemptsException ee) {
            // TODO: handle exception
            emsg = "登录失败多次，账户锁定10分钟";
            return new ModelAndView("/login").addObject("msg", emsg);
        } catch (Exception e) {
            emsg = e.getMessage();
            log.error("登录失败", e);
            emsg = "登录失败:未知错误";
            return new ModelAndView("/login").addObject("msg", emsg);
        }
    }

    /**
     * @title logout
     * @description 用户登出
     * @return ModelAndView
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public ModelAndView logout(HttpServletRequest request,
                               HttpServletResponse response) {
        // 清除用户登录数据
        SecurityUtil.getSubject().getSession()
                .removeAttribute(CommonConstants.SESSION_USER_KEY);
        return new ModelAndView("/login");
    }

    @RequestMapping(value = "/{urPath}.html")
    public ModelAndView goPageDemo(@PathVariable("urPath")String urPath){
        System.out.println(urPath);
        return new ModelAndView("/demo/"+urPath);
    }

    @RequestMapping(value = "/error/{errorCode}")
    public ModelAndView error (@PathVariable("errorCode")String errorCode) {
        return new ModelAndView("/error/"+errorCode);
    }

    /**
     * 获取真实的网络IP地址
     * @param request
     * @return
     * @throws Exception
     */
    private String getNetIP(HttpServletRequest request) throws Exception {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static void main(String[] args) {
        System.out.println(System.getProperty("java.version"));; //判断JDK版本
        System.out.println(System.getProperty("sun.arch.data.model"));; //判断是32位还是64位
        System.out.println(System.getProperty("user.name"));// 获得操作系统帐号
        Properties props= System.getProperties(); //获得系统属性集
        String osName = props.getProperty("os.name"); //操作系统名称
        String osArch = props.getProperty("os.arch"); //操作系统构架
        String osVersion = props.getProperty("os.version"); //操作系统版本
        System.out.println(osName);
        System.out.println(osArch);
        System.out.println(osVersion);
    }

}
